// import { bind, clear } from 'size-sensor';

import * as d3 from 'd3';
// import { bind, clear } from 'size-sensor';
import $ from 'jquery';
import util from './util';
import dataSourceBase from '../images/dataSourceBase.png';
import twoLevel from '../images/twoLevel.png';
import threeLevel from '../images/threeLevel.png';
import fourLevel from '../images/fourLevel.png';
import animateCircle from '../images/animateCircle.png';

const dataSourceIcon = [dataSourceBase];
export default class DataFlowGraph {
  constructor(param) {
    this.data = param.data;
    this.list = param.data.list;
    this.descriptions = param.data.descriptions;
    this.id = param.id;
    this.callBack = param.callBack;

    this.init();
  }
  /*
   * @desc 绘制画布
   */
  init() {
    this.dataBaseTemp = {};
    this.dbTableTemp = {};
    this.linesTemp = {};
    this.judgeWhetherHideDBTypeByCode = null; // 通过存储code值判断当前点击是不是同一个点 用于收起下一级
    this.judgeWhetherHideDBTableByCode = null; // 通过存储code值判断当前点击是不是同一个点 用于收起下一级
    this.scale = 1;
    this.lineIntervalWidth = 40;

    this.container = this.getContainerWH();

    if (this.container.width < 1600) {
      this.scale = 0.8;
      this.lineIntervalWidth = 20;
    }

    this.svg = this.drawSvg();

    this.drawMarker(); // 绘制箭头

    let { dataSourcePoints, dataBasePoints, lines } = this.countPoint();
    this.drawDataSourcePoint(dataSourcePoints);
    this.drawDataBasePoint(dataBasePoints);
    this.drawPath(lines);

    this.zoom();

    this.on('click', '.dataBasePoint', this.clickDataBasePoint);
    this.on('click', '.DBTypePoint', this.clickDbTypePoint);
    this.on('click', '.DBTablePoint', this.clickDbTablePoint);
  }
  getContainerWH() {
    let id = this.id;
    let ele = document.getElementById(id);
    let width = ele.clientWidth;
    let height = ele.clientHeight;
    return { width, height };
  }
  drawSvg() {
    let id = this.id;
    let { width, height } = this.container;
    let svg = d3
      .select('#' + id)
      .append('svg')
      .attr('id', 'svg')
      .attr('width', width)
      .attr('height', height);
    return svg;
  }
  drawMarker() {
    let svg = this.svg;
    let defs = svg.append('defs');

    let arrowMarker = defs
      .append('marker')
      .attr('id', 'arrow')
      .attr('markerUnits', 'strokeWidth')
      .attr('markerWidth', '18')
      .attr('markerHeight', '30')
      .attr('viewBox', '0 0 12 12')
      .attr('refX', '8')
      .attr('refY', '6')
      .attr('orient', 'auto');

    let arrowPath = 'M2,2 L10,6 L2,10 L6,6 L2,2';

    arrowMarker.append('path').attr('d', arrowPath).attr('fill', '#3176D2');
  }
  /**
   * @desc 计算点的位置
   */
  countPoint() {
    let data = JSON.parse(JSON.stringify(this.data));
    let container = this.container;
    let dataSource = data.dataSource;
    let dataBase = data.dataBase;
    let dataSourceMargin = { left: 300, top: 110 };
    let dataSourceLength = dataSource.length;
    let lines = [];
    let dataSourceLines = [];
    let interval = this.lineIntervalWidth;
    let dataSourceMiddle =
      dataSourceMargin.top + (container.height - 2 * dataSourceMargin.top) / 2;
    dataSource.map((ele, index) => {
      let x = dataSourceMargin.left;
      let y =
        dataSourceLength === 1
          ? dataSourceMiddle
          : ((container.height - 2 * dataSourceMargin.top) /
              (dataSourceLength - 1)) *
              index +
            dataSourceMargin.top;
      ele['pos'] = { x, y };
      let linePoint = { x1: x, y1: y, x2: x + interval, y2: y };
      dataSourceLines.push(linePoint);
      let pointArr = [
        [linePoint.x1, linePoint.y1],
        [linePoint.x2, linePoint.y2],
      ];
      let code = ele.code;
      this.linesTemp[code] = pointArr.slice();
    });

    lines = lines.concat(dataSourceLines);
    // 竖线
    let dataSourceVerticalLine = {
      x1: dataSourceLines[0].x2,
      y1: dataSourceLines[0].y2,
      x2: dataSourceLines[dataSourceLength - 1].x2,
      y2: dataSourceLines[dataSourceLength - 1].y2,
    };
    lines.push(dataSourceVerticalLine);

    // 竖线中点
    let dataSourceVerticalLineMiddlePoint = {
      x: dataSourceVerticalLine.x1,
      y:
        dataSourceVerticalLine.y1 +
        (dataSourceVerticalLine.y2 - dataSourceVerticalLine.y1) / 2,
    };

    // 横线
    let dataSourceHorizontalLine = {
      x1: dataSourceVerticalLineMiddlePoint.x,
      y1: dataSourceVerticalLineMiddlePoint.y,
      x2: dataSourceVerticalLineMiddlePoint.x + interval,
      y2: dataSourceVerticalLineMiddlePoint.y,
    };
    lines.push(dataSourceHorizontalLine);

    dataSource.map((ele, index) => {
      let code = ele.code;
      this.linesTemp[code].push([
        dataSourceVerticalLineMiddlePoint.x,
        dataSourceVerticalLineMiddlePoint.y,
      ]); // 横线起点
      this.linesTemp[code].push([
        dataSourceHorizontalLine.x2,
        dataSourceHorizontalLine.y2,
      ]); // 横线终点
    });

    let linesLength = lines.length;
    let dataBaseMarginTop = 60;
    let dataBaseLines = [];
    let dataBaseLength = dataBase.length;
    let dbTemp = {};
    dataBase.map((ele, index) => {
      let x = lines[linesLength - 1].x2 + interval + 1;
      let y =
        ((container.height - 2 * dataBaseMarginTop) / (dataBaseLength - 1)) *
          index +
        dataBaseMarginTop;
      ele['pos'] = { x, y };
      let linePoint = { x1: x - interval, y1: y, x2: x, y2: y, marker: true };
      dataBaseLines.push(linePoint);
      let code = ele.code;
      dbTemp[code] = ele.children;

      let pointArr = [
        [linePoint.x1, linePoint.y1],
        [linePoint.x2, linePoint.y2],
      ];
      this.linesTemp[code] = pointArr.slice();
    });

    this.dataBaseTemp = dbTemp;

    lines = lines.concat(dataBaseLines);
    // 竖线
    let dataBaseVerticalLine = {
      x1: dataBaseLines[0].x1,
      y1: dataBaseLines[0].y1,
      x2: dataBaseLines[dataBaseLength - 1].x1,
      y2: dataBaseLines[dataBaseLength - 1].y1,
    };
    lines.push(dataBaseVerticalLine);

    return {
      dataSourcePoints: dataSource,
      dataBasePoints: dataBase,
      lines: lines,
    };
  }
  drawDataSourcePoint(dataSource) {
    let svg = this.svg;
    let dataSourceG = svg.append('g').attr('class', 'dataSourceGroup');

    dataSource.forEach((ele) => {
      let pos = ele.pos;
      let dataCount = util.formatNumber(ele.dataCount);
      let todayCount = util.formatNumber(ele.todayCount);
      let dataSourceGroupPoint = dataSourceG
        .append('g')
        .attr('class', 'dataSourcePoint publicPoint')
        .attr('transform', `translate(${pos.x - 260}, ${pos.y - 100})`);

      dataSourceGroupPoint
        .append('rect')
        .attr('class', 'rect')
        .attr('width', 180)
        .attr('height', 84)
        .attr('rx', 4)
        .attr('ry', 4);

      this.drawPublicPoint({
        groupPoint: dataSourceGroupPoint,
        totalPos: { x: 10, y: 30 },
        todayPos: { x: 10, y: 60 },
        dataCount: dataCount,
        todayCount: todayCount,
      });

      dataSourceGroupPoint
        .append('image')
        .attr('class', 'iconImage')
        .attr('x', 120)
        .attr('y', 60)
        .attr('width', 140)
        .attr('height', 104)
        .attr('xlink:href', `${dataSourceBase}`);

      dataSourceGroupPoint
        .append('text')
        .attr('class', 'dataSourceName')
        .attr('dx', 220)
        .attr('dy', 160)
        .text(ele.name);
    });
  }
  drawDataBasePoint(dataBase) {
    let svg = this.svg;
    let dataBaseG = svg.append('g').attr('class', 'dataBaseGroup');

    dataBase.forEach((ele) => {
      let pos = ele.pos;
      let dataCount = util.formatNumber(ele.dataCount);
      let todayCount = util.formatNumber(ele.todayCount);
      let dataBaseGroupPoint = dataBaseG
        .append('g')
        .attr('class', 'dataBasePoint publicPoint')
        .attr('code', ele.code)
        .attr('pos', JSON.stringify(ele.pos))
        .attr('transform', `translate(${pos.x}, ${pos.y - 40})`);

      dataBaseGroupPoint
        .append('image')
        .attr('class', 'iconImage')
        .attr('x', 0)
        .attr('y', 0)
        .attr('width', 55)
        .attr('height', 64)
        .attr('xlink:href', `${twoLevel}`);

      dataBaseGroupPoint
        .append('text')
        .attr('class', 'dataBaseName')
        .attr('text-anchor', 'middle')
        .attr('dx', 25)
        .attr('dy', 80)
        .text(ele.name);

      dataBaseGroupPoint
        .append('rect')
        .attr('class', 'rect')
        .attr('x', 70)
        .attr('y', 0)
        .attr('width', 180)
        .attr('height', 84)
        .attr('rx', 4)
        .attr('ry', 4);

      this.drawPublicPoint({
        groupPoint: dataBaseGroupPoint,
        totalPos: { x: 80, y: 30 },
        todayPos: { x: 80, y: 65 },
        dataCount: dataCount,
        todayCount: todayCount,
      });
    });
  }
  clickDataBasePoint = (e) => {
    let dataBaseTemp = this.dataBaseTemp;
    let currentTarget = $(e.currentTarget);
    let code = currentTarget.attr('code');
    let pos = JSON.parse(currentTarget.attr('pos'));
    let db = dataBaseTemp[code];
    let dbLenght = db.length;
    if (dbLenght === 0) {
      return false;
    }
    this.removeDBType();
    this.removeDBTable();
    this.removeCircleAnimate();
    if (dbLenght !== 1) {
      let judgeWhetherHideDBTypeByCode = this.judgeWhetherHideDBTypeByCode;
      if (judgeWhetherHideDBTypeByCode === code) {
        this.judgeWhetherHideDBTypeByCode = null;
        return false;
      }
      this.judgeWhetherHideDBTypeByCode = code;

      let { points, lines } = this.countDBType(db, pos, code);
      this.drawDBTypePoint(points);
      this.drawPath(lines, 'DBTypePath');
    } else {
      let dbTable = db[0].children;
      let pointWight = 258;
      let dbTableMarginTop = 20;
      this.judgeWhetherHideDBTableByCode = null;
      let judgeWhetherHideDBTypeByCode = this.judgeWhetherHideDBTypeByCode;
      if (judgeWhetherHideDBTypeByCode === code) {
        this.judgeWhetherHideDBTypeByCode = null;
        return false;
      }
      this.judgeWhetherHideDBTypeByCode = code;

      let { points, lines } = this.countDBTable(
        dbTable,
        pos,
        pointWight,
        dbTableMarginTop,
        code,
      );
      this.drawDBTablePoint(points);
      this.drawPath(lines, 'DBTablePath');
    }
  };
  clickDbTypePoint = (e) => {
    let dbTableTemp = this.dbTableTemp;
    let currentTarget = $(e.currentTarget);
    let code = currentTarget.attr('code');
    let pos = JSON.parse(currentTarget.attr('pos'));
    let dbTable = dbTableTemp[code];
    if (dbTable) {
      this.removeDBTable();
      this.removeCircleAnimate();

      let judgeWhetherHideDBTableByCode = this.judgeWhetherHideDBTableByCode;
      if (judgeWhetherHideDBTableByCode === code) {
        this.judgeWhetherHideDBTableByCode = null;
        return false;
      }
      this.judgeWhetherHideDBTableByCode = code;

      let pointWight = 155;
      let dbTableMarginTop = 20;
      let { points, lines } = this.countDBTable(
        dbTable,
        pos,
        pointWight,
        dbTableMarginTop,
      );
      this.drawDBTablePoint(points);
      this.drawPath(lines, 'DBTablePath');
    }
  };
  clickDbTablePoint = (e) => {
    let id = this.id;
    let currentTarget = $(e.currentTarget);
    let code = currentTarget.attr('code');
    this.callBack(code); // 回调传回code 用于请求表描述信息
    let list = this.list[code];
    if (!list) {
      return false;
    }
    $('#' + id)
      .find('.circleAnimate')
      .children()
      .remove();

    let linesTemp = this.linesTemp;
    let animateLines = [];
    list.map((subList) => {
      let animateLinesSub = [];
      subList.map((ele) => {
        if (linesTemp[ele]) {
          animateLinesSub.push(linesTemp[ele]);
        }
      });
      animateLinesSub.push(linesTemp[code]);
      animateLines.push(animateLinesSub);
    });
    let animateLinesJoin = [];

    animateLines.map((itemSub, i) => {
      let itemSubJoin = [];
      itemSub.map((item) => {
        itemSubJoin = itemSubJoin.concat(item);
      });
      animateLinesJoin.push(itemSubJoin);
    });
    animateLinesJoin.map((item, i) => {
      code = code + i;
      const { pathThan } = util.countPaths(item);
      let duration = 8;
      let clsName = `animate_${code}`;
      let circleW = 18;
      let scale = this.scale;
      let dom = `<div
                key=${code}
                class=${clsName}
                style='position: absolute; margin: ${-circleW / 2}px 0 0 ${
        -circleW / 2
      }px; width: ${circleW}px; height: ${circleW}px; background:url(${animateCircle})'
                >
                <style>
                    .animate_${code}{
                        animation: animate_${code} ${duration}s infinite linear;
                    }
                    @keyframes animate_${code}
                    {
                        ${pathThan
                          .map((d, i) => {
                            let tx = d.path[0] * scale;
                            let ty = d.path[1] * scale;
                            let p = d.percent * 100;
                            return `${
                              p > 0 ? p - 0.001 : p
                            }% { transform: translate(${tx}px, ${ty}px) rotate(${
                              d.angle
                            }deg);}
                            ${p}% {transform: translate(${tx}px, ${ty}px) rotate(${
                              pathThan[i + 1] ? pathThan[i + 1].angle : 0
                            }deg);}`;
                          })
                          .join(' ')}
                    }
                </style>
            </div>`;
      $('#' + id)
        .find('.circleAnimate')
        .append(dom);
    });
  };
  countDBType(dbType, pos, code) {
    let lines = [];
    let container = this.container;
    let dbTableMarginTop = 50;
    // let dataBasePointW = $('.dataBasePoint').width() - 10;
    let dataBasePointW = 250;

    // 横线
    let interval = this.lineIntervalWidth;
    let horizontalLine = {
      x1: pos.x + dataBasePointW,
      y1: pos.y,
      x2: pos.x + dataBasePointW + interval,
      y2: pos.y,
      lineType: 'dashed',
    };
    lines.push(horizontalLine);

    let dbTableLength = dbType.length;

    let dbTableLines = [];
    let dbTableTemp = {};
    dbType.map((ele, index) => {
      let x = horizontalLine.x2 + interval + 1;
      let y =
        ((container.height - 2 * dbTableMarginTop) / (dbTableLength - 1)) *
          index +
        dbTableMarginTop;
      ele['pos'] = { x, y };
      let linePoint = {
        x1: x - interval,
        y1: y,
        x2: x,
        y2: y,
        lineType: 'dashed',
      };
      dbTableLines.push(linePoint);

      let code = ele.code;
      dbTableTemp[code] = ele.children;

      // 绘制路径动画用的点
      let horizontalLineArr = [
        [horizontalLine.x1, horizontalLine.y1],
        [horizontalLine.x2, horizontalLine.y2],
      ];
      let pointArr = horizontalLineArr.concat([
        [linePoint.x1, linePoint.y1],
        [linePoint.x2, linePoint.y2],
      ]);
      this.linesTemp[code] = pointArr.slice();
    });

    this.dbTableTemp = dbTableTemp;

    lines = lines.concat(dbTableLines);
    // 竖线
    let dataTableVerticalLine = {
      x1: dbTableLines[0].x1,
      y1: dbTableLines[0].y1,
      x2: dbTableLines[dbTableLength - 1].x1,
      y2: dbTableLines[dbTableLength - 1].y1,
      lineType: 'dashed',
    };
    lines.push(dataTableVerticalLine);

    return { points: dbType, lines: lines };
    // this.drawDBTypePoint(dbType);
    // this.drawPath(lines, 'DBTypePath');
  }
  countDBTable(dbTable, pos, pointWight, dbTableMarginTop) {
    let id = this.id;
    pointWight = pointWight ? pointWight : 0;

    let lines = [];
    let container = this.container;
    dbTableMarginTop = dbTableMarginTop ? dbTableMarginTop : 60;
    // let dataBasePointW = $('.dataBasePoint').width() - 20;

    // 横线
    let interval = this.lineIntervalWidth;
    let horizontalLine = {
      x1: pos.x + pointWight,
      y1: pos.y,
      x2: pos.x + pointWight + interval,
      y2: pos.y,
      lineType: 'dashed',
    };
    lines.push(horizontalLine);
    let dbTableLength = dbTable.length;
    let dbTableLines = [];
    let dbTableLenght = dbTable.length;
    dbTable.map((ele, index) => {
      let interval = this.lineIntervalWidth;
      if (dbTableLenght > 12) {
        interval = index % 2 === 0 ? interval : interval + 255;
      }
      let x = horizontalLine.x2 + interval + 1;
      let y =
        dbTableLenght === 1
          ? horizontalLine.y2
          : ((container.height - 2 * dbTableMarginTop) / (dbTableLength - 1)) *
              index +
            dbTableMarginTop;
      ele['pos'] = { x, y };
      let linePoint = {
        x1: x - interval,
        y1: y,
        x2: x,
        y2: y,
        lineType: 'dashed',
      };
      dbTableLines.push(linePoint);

      let code = ele.code;

      let horizontalLineArr = [
        [horizontalLine.x1, horizontalLine.y1],
        [horizontalLine.x2, horizontalLine.y2],
      ];
      let pointArr = horizontalLineArr.concat([
        [linePoint.x1, linePoint.y1],
        [linePoint.x2, linePoint.y2],
      ]);
      this.linesTemp[code] = pointArr.slice();
    });

    lines = lines.concat(dbTableLines);

    // 竖线
    let dataTableVerticalLine = {
      x1: dbTableLines[0].x1,
      y1: dbTableLines[0].y1,
      x2: dbTableLines[dbTableLength - 1].x1,
      y2: dbTableLines[dbTableLength - 1].y1,
      lineType: 'dashed',
    };
    lines.push(dataTableVerticalLine);

    return { points: dbTable, lines: lines };
    // this.drawDBTablePoint(dbTable);
    // this.drawPath(lines, 'DBTablePath');
  }
  drawDBTypePoint(DBType) {
    let svg = this.svg;
    let DBTypeG = svg.append('g').attr('class', 'DBTypeGroup');

    DBType.forEach((ele) => {
      let pos = ele.pos;
      let dataCount = util.formatNumber(ele.dataCount);
      let todayCount = util.formatNumber(ele.todayCount);

      let DBTypeGroupPoint = DBTypeG.append('g')
        .attr('class', 'DBTypePoint publicPoint')
        .attr('code', ele.code)
        .attr('pos', JSON.stringify(ele.pos))
        .attr('transform', `translate(${pos.x}, ${pos.y - 25})`);

      DBTypeGroupPoint.append('image')
        .attr('class', 'iconImage')
        .attr('x', 0)
        .attr('y', 10)
        .attr('width', 26)
        .attr('height', 30)
        .attr('xlink:href', `${threeLevel}`);

      DBTypeGroupPoint.append('text')
        .attr('class', 'DBTypePointName')
        .attr('text-anchor', 'middle')
        .attr('dx', 15)
        .attr('dy', 55)
        .text(ele.name);

      DBTypeGroupPoint.append('rect')
        .attr('class', 'rect')
        .attr('x', 35)
        .attr('y', 0)
        .attr('width', 120)
        .attr('height', 44)
        .attr('rx', 4)
        .attr('ry', 4);

      this.drawPublicPoint({
        groupPoint: DBTypeGroupPoint,
        totalPos: { x: 40, y: 18 },
        todayPos: { x: 40, y: 38 },
        dataCount: dataCount,
        todayCount: todayCount,
      });
    });
  }
  drawDBTablePoint(dbTable) {
    let svg = this.svg;
    let dbTableG = svg.append('g').attr('class', 'DBTableGroup');

    dbTable.forEach((ele) => {
      let pos = ele.pos;
      let code = ele.code;
      let dataCount = util.formatNumber(ele.dataCount);
      let todayCount = util.formatNumber(ele.todayCount);
      let name = ele.name.substring(0, 7);
      let descriptions = this.descriptions[code] ? this.descriptions[code] : '';
      let descArr = util.cutOutString(descriptions);

      let dbTableGroupPoint = dbTableG
        .append('g')
        .attr('class', 'DBTablePoint publicPoint')
        .attr('code', ele.code)
        .attr('pos', JSON.stringify(ele.pos))
        .attr('transform', `translate(${pos.x}, ${pos.y - 25})`);

      dbTableGroupPoint.append('title').text(`${descArr.join('\r\n')}`);

      dbTableGroupPoint
        .append('image')
        .attr('class', 'iconImage')
        .attr('x', 0)
        .attr('y', 14)
        .attr('width', 16)
        .attr('height', 21)
        .attr('xlink:href', `${fourLevel}`);

      dbTableGroupPoint
        .append('rect')
        .attr('class', 'DBTablePointNameRect')
        .attr('x', 20)
        .attr('y', 12)
        .attr('width', 100)
        .attr('height', 24)
        .attr('rx', 2)
        .attr('ry', 2);

      dbTableGroupPoint
        .append('text')
        .attr('class', 'DBTablePointName')
        .attr('width', 100)
        .attr('height', 24)
        .attr('text-anchor', 'middle')
        .attr('dx', 70)
        .attr('dy', 28)
        .text(name);

      dbTableGroupPoint
        .append('rect')
        .attr('class', 'rect')
        .attr('x', 130)
        .attr('y', 0)
        .attr('width', 120)
        .attr('height', 44)
        .attr('rx', 4)
        .attr('ry', 4);

      this.drawPublicPoint({
        groupPoint: dbTableGroupPoint,
        totalPos: { x: 135, y: 18 },
        todayPos: { x: 135, y: 38 },
        dataCount: dataCount,
        todayCount: todayCount,
      });
    });
  }
  drawPublicPoint(param) {
    let { groupPoint, totalPos, todayPos, dataCount, todayCount } = param;

    let totalText = groupPoint
      .append('text')
      .attr('class', 'total')
      .attr('x', totalPos.x)
      .attr('y', totalPos.y);
    totalText
      .append('tspan')
      .attr('class', 'name')
      .attr('dx', 0)
      .attr('dy', 0)
      .text('来源总量');
    totalText
      .append('tspan')
      .attr('class', 'value')
      .attr('dx', 5)
      .attr('dy', 0)
      .text(dataCount);

    let todayText = groupPoint
      .append('text')
      .attr('class', 'today')
      .attr('x', todayPos.x)
      .attr('y', todayPos.y);
    todayText
      .append('tspan')
      .attr('class', 'name')
      .attr('dx', 0)
      .attr('dy', 0)
      .text('今日新增');
    todayText
      .append('tspan')
      .attr('class', 'value')
      .attr('dx', 5)
      .attr('dy', 0)
      .text(todayCount);
  }
  drawPath(lines, className) {
    let svg = this.svg;
    let clsName = className ? className : 'path';
    lines.forEach((item) => {
      let marker = item.marker;
      let lineType = item.lineType;
      let line = [
        { x: item.x1, y: item.y1 },
        { x: item.x2, y: item.y2 },
      ];
      let lines = svg
        .append('path')
        .attr('class', clsName)
        .attr('d', this.lineFunction()(line))
        .attr('stroke', '#54c2f1')
        .attr('stroke-width', 1)
        .attr('fill', 'none');
      if (lineType === 'dashed') {
        lines.attr('stroke-dasharray', '2');
      }
      if (marker) {
        lines.attr('marker-end', 'url(#arrow)');
      }
    });
  }
  zoom() {
    let scale = this.scale;
    let { width, height } = this.container;
    let x = (width - width * scale) / 2;
    let y = (height - height * scale) / 2;
    this.svg.style('transform', `translate(-${x}px, -${y}px) scale(${scale})`);
  }
  removeDBType() {
    let svg = this.svg;
    svg.selectAll('.DBTypePath').remove();
    svg.select('.DBTypeGroup').remove();
  }
  removeDBTable() {
    let svg = this.svg;
    svg.selectAll('.DBTablePath').remove();
    svg.select('.DBTableGroup').remove();
  }
  removeCircleAnimate() {
    let id = this.id;
    $('#' + id)
      .find('.circleAnimate')
      .children()
      .remove();
  }
  // 线生成器
  lineFunction() {
    let lineFun = d3
      .line()
      .x(function (d) {
        return d.x;
      })
      .y(function (d) {
        return d.y;
      });
    return lineFun;
  }
  on(eventName, domObj, fun) {
    $(document).on(eventName, domObj, (e) => {
      fun(e);
    });
  }
}
